package org.ztest.classloader;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;

/**
 * 自定义类加载器，从指定路径下面加载指定class文件
 * @author lhl
 *
 * 2015年7月20日下午4:00:08
 */
public class MyClassLoader extends ClassLoader
{
	private static final String PATH_PREFIX = "F:\\workspace\\Demo\\ztest\\target\\classes\\";
	private HashSet<String> className; // 要加载的类名
	
	/**
	 * @param classes 注意：使用类全名，比如com.xx.App
	 */
	public MyClassLoader(String... classes)
	{
		className = new HashSet<String>();
		preLoad(classes);
	}
	
	/**
	 * 预加载
	 * @param clazns
	 */
	private void preLoad(String[] classes)
	{
		for (int i = 0; i < classes.length; i++)
		{
			generateClass(classes[i]);
			className.add(classes[i]);
		}
	}
	
	/**
	 * 生成类
	 * @param name
	 * @return
	 */
	public Class<?> generateClass(String name)
	{
		byte[] classData = loadClassBytes(name);
		return defineClass(name, classData, 0, classData.length);
	}
	
	/**
	 * 加载类的二进制内容
	 * @param name
	 * @return
	 */
	protected byte[] loadClassBytes(String name)
	{
		name = name.replace('.', File.separatorChar).concat(".class");
		String path = PATH_PREFIX.concat(name);
		System.out.println("Path is " + path);
		try
		{
			return Files.readAllBytes(Paths.get(path));
		}
		catch (IOException e)
		{
			throw new RuntimeException(e);
		}
	}
	
	@Override
	protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
	{
		Class<?> cls = null;
		cls = findLoadedClass(name);
		if (!this.className.contains(name) && cls == null)
		{
			cls = getSystemClassLoader().loadClass(name);
		}
		if (cls == null)
		{
			throw new ClassNotFoundException();
		}
		if (resolve)
			resolveClass(cls);
		return cls;
	}
}
